function UKey() {
	var self = this;
	var _data = null;
	var _message = null;
	var _isSmallScreen = true;
	var _mShowListId = 'c';
	var _unSelectedCharacterList = null;
	var _selectedCharacterList = null;
	var _unMatchedTaxaList = null;
	var _matchedTaxaList = null;
	var _parameter;
	
	this.init = function(isSmallScreen) {
		_isSmallScreen = isSmallScreen;
		_message = UMessage.getInstance();
	}
	this.loadData = function() {
		var paramerter = UUtil.getParameters();
		_parameter = paramerter;
		if ( !paramerter ) {
			showMessage('Missing parameter: data\n e.g. datasetId=1');
			return;			
		} 
		if ( !UUtil.isNull(paramerter.id) ) {
			var data = UStorage.getInstance().findById(paramerter.id);	
			if ( data ) {
				$.mobile.showPageLoadingMsg();
				_data = UStorage.getInstance().getData(data.id);
				updateUI();
				return;
			}
		} else if ( !UUtil.isNull(paramerter.datasetId) ) {
			$.mobile.showPageLoadingMsg();
			load('php/data.php?datasetId=' + paramerter.datasetId, onloadDataReady, onloadDataError);
		} else {
			showMessage('Missing parameter: data\n e.g. data=http://flora.huh.harvard.edu/china/delta/Acer/Acer.ink');
			return;
		}
	};
	
	this.loadSavedData = function(id) {
		var data = UStorage.getInstance().findById(id);	
		if ( !data ) {
			return;
		}
		_data = UStorage.getInstance().getData(data.id);
		updateUI();
	}
	
	function onloadDataReady(result) {
		$.mobile.hidePageLoadingMsg();
		if ( !result) {
			showMessage('Failed to load dataset');
			return;
		}
		_data = result;
		if ( _data.messages ) {
			onLoadMessageReady(_data.messages);
		} else {
			if ( _parameter && _parameter.lang && _parameter.lang.length > 0) {
				load('php/getMessage.php?datasetId=' + _data.id + "&lang=" + _parameter.lang, onLoadMessageReady, onMessageLoadError);
			} else {
				updateUI();
			}
		}
//		test();
	}
	
	function onLoadMessageReady(result) {
		_message.onLoadMessageReady(result);
		updateUI();
	}
	function onMessageLoadError(result) {
		updateUI();
	}	
	
	function onloadDataError(xhr) {
		$('#uTitle').html('Failed'); 
		$('#uInkURL').html('Failed to load dataset, try again later'); 
	}
	
	function test() {
		var uData = UData.getInstance();
		var c = uData.findCharacterById(19);
		c.enteredValue = 5;
		c.selectedValues = [];
		c.selectedValues[0] = 1;
		uData.selectCharacter(c);
	}	
	
	this.onShowTab = function(mShowListId) {
		_mShowListId = mShowListId;
		showList();
	};
	function showList() {
		var t = '';
		if ( _mShowListId == 'c' ) {
			t = showCharacterList(_unSelectedCharacterList);
		} else if ( _mShowListId == 'cs' ) {
			t = showCharacterListSelectted(_selectedCharacterList);
		} else if ( _mShowListId == 't' ) {
			t = showTaxaList(_unMatchedTaxaList, _selectedCharacterList);
		} else if ( _mShowListId == 'ts' ) {
			t = showTaxaListSelected(_matchedTaxaList, _selectedCharacterList);
		}
		$('#uPK_content_m_list').html(t).trigger("create");
	}
		
	
	function updateUI() {
		if ( !_data) {
			return;
		}
		
		var title = _message.get('title');
		if ( UUtil.isNull(title)) {
			title = UUtil.nullToNone(_data.title); 			
		} 
		$('#uTitle').html(title); 
		
		if ( UUtil.isNull(_data.inkURL)) {
			$('#uInkURL').hide(); 
		} else {
			$('#uInkURL').html(_data.inkURL);
		}
		
		var description = _message.get('description');
		if ( UUtil.isNull(description)) {
			title = _data.description; 			
		} 		
		if ( UUtil.isNull(description) ) {
			$('#uSubTitle').hide();
		} else {
			$('#uSubTitle').html(description); 
		}
		
		if ( !_data.characters || _data.characters.length < 1) {
			showMessage('Failed to load characters');
			return;
		}
		
		if ( !_data.taxa || _data.taxa.length < 1) {
			showMessage('Failed to load taxa');
			return;
		}			
		
		self.updateUI(_data.characters, null, _data.taxa, null);
	}
	
	this.saveDataSet = function() {
		if ( _data ) {
			if ( !UStorage.getInstance().isSupport() ) {				
				t = 'Your browser does not support offline storage. ';
				alert(t);
				return;
			}
			storageData();		
			alert('Dataset added');
		}
	}
		
	this.updateUI_m = function(unSelectedCharacterList, selectedCharacterList, unMatchedTaxaList, matchedTaxaList) {
		_unSelectedCharacterList = unSelectedCharacterList;
		_selectedCharacterList = selectedCharacterList;
		_unMatchedTaxaList = unMatchedTaxaList;
		_matchedTaxaList = matchedTaxaList;
		
		var t;
		t = _message.get('character') + ' ' + getSize(_unSelectedCharacterList) + '';
		$('#uPK_content_m_tab_c').html(t);

		t = _message.get('selected') + ' ' + getSize(_selectedCharacterList) + '';
		$('#uPK_content_m_tab_cs').html(t);

		t = _message.get('taxa') + ' ' + getSize(_unMatchedTaxaList) + '';
		$('#uPK_content_m_tab_t').html(t);
		
		t = _message.get('matched') + ' ' + getSize(_matchedTaxaList) + '';
		$('#uPK_content_m_tab_ts').html(t);
		
		showList();
	};		
	
	function storageData() {
		var storage = UStorage.getInstance();
		if ( !storage.isSupport() ) {
			return;
		} 		
		storage.saveDataSet(_data);
	}
	
	this.updateUI = function(unSelectedCharacterList, selectedCharacterList, unMatchedTaxaList, matchedTaxaList) {
		if ( _isSmallScreen ) {
			self.updateUI_m(unSelectedCharacterList, selectedCharacterList, unMatchedTaxaList, matchedTaxaList);
			return;
		}
		var t = '', c;
		t += '<div class="ui-grid-c">';
		t += '<div class="ui-block-a">';
		c = showCharacterList(unSelectedCharacterList);
		if ( !UUtil.isNull(c)) {
			t += c;
		}
		t += '</div>';
		
		t += '<div class="ui-block-b">';
		c = showCharacterListSelectted(selectedCharacterList);
		if ( !UUtil.isNull(t)) {
			t += c;
		}
		t += '</div>';
		
		t += '<div class="ui-block-c">';
		c = showTaxaList(unMatchedTaxaList, selectedCharacterList);
		if ( !UUtil.isNull(t)) {
			t += c;
		}	
		t += '</div>';
		
		t += '<div class="ui-block-d">';
		c = showTaxaListSelected(matchedTaxaList, selectedCharacterList);
		if ( !UUtil.isNull(t)) {
			t += c;
		}	
		t += '</div>';
		
		$('#uPK_content').html(t).trigger("create");
	};
	
	function showCharacterList(characterList) {		
		var t = '';
		t += '<ul  data-role="listview" data-inset="true">';
		if ( !_isSmallScreen ) {
			t += '<li data-role="list-divider" class="uLI">' + _message.get('characters') + ' ('+ getSize(characterList) + ')</li>';
		}
		if ( characterList ) {		
			var len = characterList.length;	
			for (var i=0; i<len; i++) {
				var c = characterList[i];
				t += '<li class="uLI">';
				t += '<a href="#uPageCharacter?cId=' + c.id + '" data-rel="dialog" data-transition="pop">';
				$msg = _message.getOnly('c' + c.id);
				if ( UUtil.isNull($msg)) {
					$msg = c.name;
				}
				t += UUtil.escapeHTML($msg);
				t += '</a>';
				t += '</li>';
			}
		}
		t += '</ul>';
		return t;
	}
	
	function showCharacterListSelectted(characterList) {
		var t = '';
		t += '<ul  data-role="listview" data-split-icon="delete" data-inset="true">';
		if ( !_isSmallScreen ) {
			t += '<li data-role="list-divider" class="uLI">' + _message.get('selected') + ' ('+ getSize(characterList) + ')</li>';
		}
		if ( characterList ) {
			var len = characterList.length;		
			for (var i=0; i<len; i++) {
				var c = characterList[i];
				t += '<li class="uLI">';
				t += '<a href="#uPageCharacter?cId=' + c.id + '" data-rel="dialog" data-transition="pop">';
				$msg = _message.getOnly('c' + c.id);
				if ( UUtil.isNull($msg)) {
					$msg = c.name;
				}
				t += UUtil.escapeHTML($msg);
				t += '<br/><br/><p>' + getCharacterValueDisplay(c) + '</p>';
				t += '</a>';
				
				t += '<a href="javascript:UCharacter.getInstance().removeCharacter(' + c.id + ');">';
				t += c.name;
				t += '</a>';
				
				t += '</li>';
			}
		}
		t += '</ul>';
		return t;
	}	
	
	function showTaxaList(taxaList, characterList) {	
		var t = '';
		t += '<ul data-role="listview" data-inset="true">';
		if ( !_isSmallScreen ) {
			t += '<li data-role="list-divider" class="uLI">' + _message.get('taxa') + ' ('+ getSize(taxaList) + ')</li>';
		}
		if ( taxaList ) {
			var len = taxaList.length;
			for (var i=0; i<len; i++) {
				var taxon = taxaList[i];
				t += '<li class="uLI">';
				t += '<a href="#uPageTaxon?tId=' + taxon.id + '" data-rel="dialog" data-transition="pop">';
				t += showTaxaThumbNailImages(taxon.images);
				$msg = _message.getOnly('t' + taxon.id);
				if ( !UUtil.isNull($msg)) {
					$msg = $msg + '<br/>';
				} else {
					$msg = '';
				} 
					
				t += '<h3  style="text-transform: none;">' + $msg +  UUtil.escapeHTML(taxon.name) + '</h3>';
				t += showTaxaListGetAttributeValue(taxon, characterList);
				t += '</a>';
				
				
				t += '</li>';				
			}
		}
		t += '</ul>';
		return t;
	}
	
	function showTaxaListSelected(taxaList, characterList) {
		var t = '';
		t += '<ul data-role="listview" data-inset="true">';
		if ( !_isSmallScreen ) {
			t += '<li data-role="list-divider" class="uLI">' + _message.get('matched') + ' ('+ getSize(taxaList) + ')</li>';
		}
		if ( taxaList ) {
			var len = taxaList.length;
			for (var i=0; i<len; i++) {
				var taxon = taxaList[i];
				t += '<li class="uLI">';
				t += '<a href="#uPageTaxon?tId=' + taxon.id + '" data-rel="dialog" data-transition="pop">';
				t += showTaxaThumbNailImages(taxon.images); 
				$msg = _message.getOnly('t' + taxon.id);
				if ( UUtil.isNull($msg)) {
					$msg = taxon.name;
				}
				t += '<h3  style="text-transform: none;">' +  UUtil.escapeHTML($msg) + '</h3>';
				t += showTaxaListGetAttributeValue(taxon, characterList);
				t += '</a>';
				
				t += '</li>';
			}
		}
		t += '</ul>';
		return t;
	}	
	
	
	function showTaxaThumbNailImages(images) {
		if ( !images || images.length < 1 ) {
			return '';
		}
		var t = '';
		var image = images[0];
		var url = UUtil.getTaxaThumbNailImage(_data, image.f);
		if ( !UUtil.isNull(url)) {
			t += '<IMG src="' + url + '"/>';
		}
		return t;
	}	
	
	function showTaxaListGetAttributeValue(taxon, characterList) {
		var t = '';
		
		if ( !characterList  ) {
			return t;
		}
		var uData = UData.getInstance();
		for (var j=0; j<characterList.length; j++) {
			var c = characterList[j];
			var attValue = uData.findTaxonAttribute(taxon, c);	

			t += '<p>';
			$msg = _message.getOnly('c' + c.id);
			if ( UUtil.isNull($msg)) {
				$msg = c.name;
			}
			t += $msg + ": ";
			if ( attValue ) {
				t += self.attributeToString(c, attValue);												
			} else {
				t += 'n/a';						
			}
			t += '</p>';
		}
		return t;
	}
	
	function getSize(list) {
		if ( list && list.length ) {
			return list.length;
		} else {
			return 0;
		}
	}	
	
	this.attributeToString = function(character, attValue) {
		
		if ( character == null || attValue == null ) {
			return null;
		}
		
		var values = [];
		switch (character.type) {
		case UUtil.CHARACTER_TYPE_OrderedMultiState:
		case UUtil.CHARACTER_TYPE_UnorderedMultiState:
			if ( UUtil.isArray(attValue) ) {
				if ( attValue.length > 0 ) {
					for (var i=0; i<attValue.length; i++) {
						values.push( _message.getCharacterState(character, attValue[i], character.states) );
					}
				}
			} else {
				if ( attValue > 0 ) {
					values.push( _message.getCharacterState(character, attValue, character.states) );
				}
			}
			break;
		default:			
			if ( UUtil.isArray(attValue) ) {
				for (var i=0; i<attValue.length; i++) {
					values.push(attValue[i]);
				}
			} else if ( !UUtil.isUndefined(attValue.min) && !UUtil.isUndefined(attValue.max) ) {
				values.push(attValue.min + '-' + attValue.max);
			} else {
				
				if ( UUtil.isString(attValue) ) {
					if ( !UUtil.isNull(attValue) ) {
						values.push(attValue);
					}
				} else {
					if ( attValue != 0 ) {
						values.push(attValue);
					}
				}
			}
			break;
		}		
		return values.join(',');
	}
	
	function getCharacterValueDisplay(c) {
		var values = [];
		if ( !UUtil.isNull(c.enteredValue) ) {
			values.push(c.enteredValue);
		}
		if ( c.selectedValues && c.selectedValues.length > 0 ) {
			for (var i=0; i<c.selectedValues.length; i++) {
				var v = _message.getCharacterState(c, c.selectedValues[i], c.states);
				if ( !UUtil.isNull(v) ) {
					values.push(v);
				}
			}
		}
		return values.join(',');
	}
	
	function outImages(images) {
		if ( !images || images.length < 1 ) {
			return '';
		}
		var t = '';
		t += '<p>';
		for (var i=0; i<images.length; i++) {
			var image = images[i];
			var url = UUtil.getImageURL(image);
			if ( !UUtil.isNull(url)) {
				t += image.f;
			}
		}
		t += '</p>';
		return t;
	}

	
	function showMessage(message) {
		alert(message);
	}
	
	function load(page, callbackSuccess, callbackError) {
		$.ajax({
			  url: page,
			  dataType: 'json',
			  data: null,
			  success: callbackSuccess, 
			  error:callbackError
			});
//		 $.ajax({url:page, success:callback});
	}
	
	this.getData = function() {
		return _data;
	};
	
	this.doSlideShow = function() {
		if ( !_data ) {
			return;
		}
		var MAX_NUMBER_OF_IMAGES = 14;
		
		var t = '';
		var cnt = 0;
		for (var i=0; i<_data.taxa.length; i++) {
			var taxon = _data.taxa[i];
			var images = taxon.images;
			if ( !images || images.length < 1 ){
				continue;
			}
			for (var j=0; j<images.length; j++) {
				var image = images[j];
				if ( image && !UUtil.isNull(image.f) ) {
					t += doSlideShowAddOne(image, taxon);
					cnt++;
					if ( cnt >= MAX_NUMBER_OF_IMAGES ) {
						break;
					}
				}
			}
			if ( cnt >= MAX_NUMBER_OF_IMAGES ) {
				break;
			}			
		}
		if ( UUtil.isNull(t) ) {
			$('#uPSlide_content').html('No Images').trigger("create");			
		} else {
			$('#uPS_slidesContainer').html(t).trigger("create");	
		}		
	}
	
	function doSlideShowAddOne(image, taxon) {
		var t = '';
	
		var url = UUtil.getTaxaMobileImage(_data, image.f);
		if ( UUtil.isNull(url)) {
			return t;
		}
		
		t += '<div class="slide">';
		t += '<a href="' + url + '" target="_blank">';
		
		t += '<img class="uSlideImage" src="' + url + '"/>';
		t += '</a>';
		t += '<div class="caption" style="bottom: 0">';
		t += '<p>';
		t += UUtil.escapeHTML(taxon.name);
		t += '</p>'
		t += '</div>';
		t += '</div>';
		
		return t;
	}
}

UKey.getInstance = function() {
	if ( UKey._instance == null ) {
		UKey._instance = new UKey();
	}
	return UKey._instance;
};

